using IQIGame.Onigao.Framework;
using NetProtocol.POD;
using System;
using System.Collections.Generic;

namespace IQIGame.Onigao.GamePlay
{
    public class DynLevelRegion
    {
        public BetterList<int, DynLevelHeroEntity> dynHeroEntitys { protected set; get; } = new BetterList<int, DynLevelHeroEntity>();
        public BetterList<int, DynLevelEntity> dynLevelEntitys { protected set; get; } = new BetterList<int, DynLevelEntity>();
        public int cid { private set; get; }

        public int customBgmCid { private set; get; }
        public LevelRegionPackConfig packConfig { protected set; get; }
        public Dictionary<int, int> customWeathers { private set; get; }
        public List<int> effectCids { get; private set; }

        protected DynLevelRegion(LevelRegionPOD pod, LevelRegionPackConfig packConfig)
        {
            this.cid = packConfig.cfgRegionInstance.Id;
            this.packConfig = packConfig;
            this.customBgmCid = pod.customBgmCid;
            this.customWeathers = pod.customWeathers;
            this.effectCids = pod.effectCids;
        }

        protected virtual void CreateDynEntitysByPOD(List<LevelEntityPOD> Entities)
        {
            dynHeroEntitys.Clear();
            dynLevelEntitys.Clear();
            var regionPackConfig = LevelPlayUtil.GetRegionPackConfig();
            foreach (var e in Entities)
            {
                if (e.IsHero())
                {
                    var heroEntity = DynLevelHeroEntity.CreateByPOD(e);
                    dynHeroEntitys.Add(e.id, heroEntity);
                }
                else
                {
                    if (e.IsRemoved)
                    {
                        continue;
                    }
                    var levelEntity = DynLevelEntity.CreateByPOD(e);
                    dynLevelEntitys.Add(e.id, levelEntity);
                }
            }
        }

        public bool RemoveDynEntity(int id, out DynLevelEntity dynLevelEntity)
        {
            if (!dynLevelEntitys.TryGetValue(id, out dynLevelEntity))
            {
                return false;
            }
            return dynLevelEntitys.Remove(id);
        }

        public bool RemoveDynEntity(int id)
        {
            return dynLevelEntitys.Remove(id);
        }

        public DynLevelHeroEntity UpdateDynHeroEntity(LevelEntityPOD pod)
        {

            if (dynHeroEntitys.TryGetValue(pod.id, out var dynEntity))
            {
                dynEntity.UpdateByPOD(pod);
                return dynEntity;
            }
            var heroEntity = DynLevelHeroEntity.CreateByPOD(pod);
            dynHeroEntitys.Add(pod.id, heroEntity);
            return heroEntity;
        }

        /// <summary>
        /// 更新实体整体数据时调用
        /// </summary>
        /// <param name="pod"></param>
        /// <param name="isPos2DChanged"></param>
        /// <returns></returns>
        public DynLevelEntity UpdateDynEntity(LevelEntityPOD pod, out bool isPos2DChanged, out bool isPosYChanged)
        {
            isPos2DChanged = false;
            isPosYChanged = false;
            if (dynLevelEntitys.TryGetValue(pod.id, out var dynEntity))
            {
                float oldX = dynEntity.x;
                float oldZ = dynEntity.z;
                float oldY = dynEntity.y;
                dynEntity.UpdateByPOD(pod);
                isPos2DChanged = Math.Abs(oldX - dynEntity.x) > 0.001f || Math.Abs(oldZ - dynEntity.z) > 0.001f;
                isPosYChanged = Math.Abs(oldY - dynEntity.y) > 0.001f;
                return dynEntity;
            }
            var regionPackConfig = LevelPlayUtil.GetRegionPackConfig();
            var levelEntity = DynLevelEntity.CreateByPOD(pod);
            dynLevelEntitys.Add(pod.id, levelEntity);
            return levelEntity;
        }

        public bool ChangeCustomBgm(int customBgmCid)
        {
            if (this.customBgmCid == customBgmCid)
            {
                return false;
            }
            this.customBgmCid = customBgmCid;
            return true;
        }

        public bool ChangeWeather(int id, int type)
        {
            if (!customWeathers.TryGetValue(id, out int oldType))
            {
                customWeathers.Add(id, type);
                return true;
            }
            if (oldType == type)
            {
                return false;
            }
            customWeathers[id] = type;
            return true;
        }

        public static DynLevelRegion CreateByPOD(LevelRegionPOD pod, LevelRegionPackConfig packConfig)
        {

            var region = new DynLevelRegion(pod, packConfig);

            region.CreateDynEntitysByPOD(pod.entities);
            //回收POD，该POD可回收：LevelEntityPOD.DynamicFactory = PODPool<LevelEntityPOD>.Init(10);
            foreach (var entityPOD in pod.entities)
            {
                PODPool<LevelEntityPOD>.Put(entityPOD);
            }
            return region;
        }
    }
}
